﻿
using hentity;
using hutil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 namespace hcache {
    /**
   *┌────────────────────────────────────────────────┐
   *│　描    述：TransferChain                                                    
   *│　作    者：sgj                                              
   *│　版    本：1.0                                              
   *│　创建时间：2020/10/10 9:12:53                        
   *└────────────────────────────────────────────────┘
   **/
     public class Node : RAM,CacheData {
        public int eid;
        public int R { get; }
        public List<BStn> dbStns = new List<BStn>();

        public List<int[]> rangeList = new List<int[]>();
        public bool isKeyStn = false;//是否是关键点
        public List<Edge> beforeEdge = new List<Edge>();//当前点的边
        public List<Edge> nextEdge = new List<Edge>();//当前点的边
        public List<long> timeAxis = new List<long>();
        public long current = 0;

       public int hasTasks() {
            return timeAxis.Count;


        }
        public int getCurrentTaskEmplyNode() {//系统确定先执行的任务
             int node = 0;
            Estimate n = MyCache.getValue<Estimate>("" + current) ;
            while( n != null ) {
                var node1 = TransferConfigFacade.getConfig(n.nodeId);
                if( node1.getWaitTime() > 0 ) {
                    break;
                }
                n = MyCache.getValue<Estimate>("" + n.nextEstimateId)  ;
                node++;
            }
            return node;
        }
         public int getPredictTime() {
             return R + getWaitTime();
        }
        public int getWaitTime() {
            int dynamicR = 0;
            Estimate e = MyCache.getValue<Estimate>("" + current);
            if( e != null ) {
                dynamicR +=e .getWaitTime();
            }
            return dynamicR;
        }
        public void setTask(int taskNo) {
            for(int i=0;i< timeAxis.Count;i++ ) {
                Estimate e = MyCache.getValue<Estimate>("" + timeAxis[i]);
                if( e == null ) {
                    timeAxis.RemoveAt(i);
                    i--;
                    continue;
                }
                if( e.taskNo == taskNo ) {
                    current = e.id;
                    e.arrived();
                    return;
                }
            }
        }
        public Estimate getEstimate(int  taskNo) {
            List<BaseTask> list = new List<BaseTask>();
            for( int i = 0;i < timeAxis.Count;i++ ) {
                Estimate e = MyCache.getValue<Estimate>("" + timeAxis[i]);
                if( e == null ) {
                    throw new Exception(eid + "时间轴异常");
                }
                if( e.taskNo == taskNo ) {
                    return e;
                }
            }
            return null;


        }
    
         public Node tmpBefore;//临时变量
        public int tmpBeforDistance;//临时变量，距离
        public void clearTmp() {
            tmpBefore = null;
            tmpBeforDistance = int.MaxValue;
            for( int i = 0;i < timeAxis.Count;i++ ) {
                Estimate e = MyCache.getValue<Estimate>("" + timeAxis[i]);
                if( e == null ) {
                    timeAxis.RemoveAt(i);
                    i--;

                }
            }
        }
        public int getDistance(Node t) {
            foreach( Edge edge in nextEdge ) {
                if( edge.getDes() == t ) {
                    return edge.R;
                }
            }
            return int.MaxValue;
        }
        public Node(BStn stn) {
            this.eid = stn.eid;
            this.R = stn.distance;
            dbStns.Add(stn);
        }
        public void addConfig(BStn physicalStn) {
            isKeyStn = isKeyStn || physicalStn.isKeyPoint == 1;
            int[] range = new int[] { physicalStn.rangeBegin ,physicalStn.rangeEnd };
            rangeList.Add(range);
            if( !dbStns.Contains(physicalStn) ) {
                dbStns.Add(physicalStn);
            }
          
        }
        public void addGoalConfig(Node t ,Type driveType ,BStnRelation physical ) {
            int weigth = physical.distance;
            foreach( Edge e in nextEdge ) {
                if( e.getDes() == t ) {
                    return;
                }
            }
            Edge edge = new Edge(this ,physical ,driveType ,t);
            TransferConfigFacade.allEdge.Add(edge);
        }
        public bool isConfig(int eid) {
            if( this.eid == eid ) {
                return true;
            }
            foreach( var range in this.rangeList ) {
                if( range[0] <= eid && range[1] >= eid ) {
                    return true;
                }
            }
            return false;
        }
        public long getFreeTime(long beginOccupy ,Estimate me) {//当前节 可以接任务时间
            List<Estimate> estimates = new List<Estimate>();
            for( int i = 0;i < timeAxis.Count;i++ ) {
                long id = timeAxis[i];
                Estimate e = MyCache.getValue<Estimate>("" + id);
                if( e != null ) {
                    estimates.Add(e);
                } else {
                    timeAxis.RemoveAt(i);
                    i--;
                }
            }


      
            estimates.Sort(delegate (Estimate x ,Estimate y) { return ( int ) (x.beginOccupy - y.beginOccupy); });
            for( int i = 0;i < estimates.Count;i++ ) {
                Estimate estimate = estimates[i];
                if( estimate.finshOccupy < beginOccupy || me == estimate ) {//没有到达时我不管
                    continue;
                }
                if( estimate.beginOccupy > beginOccupy ) {//后面有其他计划了，但当前计划比其他计划早到并且不影响其他计划
                    return beginOccupy;
                }
                if( estimate.finshOccupy > beginOccupy ) {
                    beginOccupy = estimate.finshOccupy;
                }
            }
            return beginOccupy;
        }

        public string getId () {
            return eid + "";
        }
    }
}
